//! Raft HTTP network layer scaffold (multi-node support placeholder)
//!
//! This module defines HTTP endpoints and client stubs for Raft RPC:
//!  - AppendEntries
//!  - Vote
//!  - InstallSnapshot
//! Actual OpenRaft trait integration will be implemented later.

use axum::{extract::State, routing::post, Json, Router};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use tracing::info;

#[derive(Clone)]
pub struct RaftRpcService {
    pub node_id: crate::NodeId,
}
impl RaftRpcService {
    pub fn new(node_id: crate::NodeId) -> Self {
        Self { node_id }
    }
}

// Placeholder request/response DTOs (not actual OpenRaft types)
#[derive(Debug, Serialize, Deserialize)]
pub struct AppendEntriesRequest {
    pub term: u64,
    pub leader_id: u64,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct AppendEntriesResponse {
    pub term: u64,
    pub success: bool,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct VoteRequest {
    pub term: u64,
    pub candidate_id: u64,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct VoteResponse {
    pub term: u64,
    pub vote_granted: bool,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct InstallSnapshotRequest {
    pub term: u64,
    pub leader_id: u64,
    pub last_included_index: u64,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct InstallSnapshotResponse {
    pub term: u64,
}

#[derive(Clone)]
pub struct RaftNetworkState {
    pub service: Arc<RaftRpcService>,
}

pub fn router(state: RaftNetworkState) -> Router {
    Router::new()
        .route("/append", post(handle_append_entries))
        .route("/vote", post(handle_vote))
        .route("/install_snapshot", post(handle_install_snapshot))
        .with_state(state)
}

async fn handle_append_entries(
    State(_state): State<RaftNetworkState>,
    Json(req): Json<AppendEntriesRequest>,
) -> Json<AppendEntriesResponse> {
    info!(
        "append_entries received from leader {} term {}",
        req.leader_id, req.term
    );
    Json(AppendEntriesResponse {
        term: req.term,
        success: true,
    })
}
async fn handle_vote(
    State(_state): State<RaftNetworkState>,
    Json(req): Json<VoteRequest>,
) -> Json<VoteResponse> {
    info!("vote request from {} term {}", req.candidate_id, req.term);
    Json(VoteResponse {
        term: req.term,
        vote_granted: true,
    })
}
async fn handle_install_snapshot(
    State(_state): State<RaftNetworkState>,
    Json(req): Json<InstallSnapshotRequest>,
) -> Json<InstallSnapshotResponse> {
    info!(
        "install snapshot leader {} term {}",
        req.leader_id, req.term
    );
    Json(InstallSnapshotResponse { term: req.term })
}

#[derive(Clone)]
pub struct RaftRpcClient {
    base: String,
    http: reqwest::Client,
}
impl RaftRpcClient {
    pub fn new(addr: &str) -> crate::Result<Self> {
        Ok(Self {
            base: format!("http://{}", addr),
            http: reqwest::Client::new(),
        })
    }
}
